package top.ezzz.rpc.util;

import com.google.protobuf.Message;
import com.google.protobuf.util.JsonFormat;
import lombok.extern.slf4j.Slf4j;
import org.noear.snack.ONode;
import org.noear.snack.core.NodeDecoder;
import org.noear.snack.core.NodeEncoder;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
import org.noear.solon.serialization.snack3.SnackActionExecutor;
import org.noear.solon.serialization.snack3.SnackRenderFactory;

import java.lang.reflect.Type;


@Slf4j
@Configuration
public class GrpcMessageConfig {

    @Bean
    public void jsonInit(@Inject SnackRenderFactory factory, @Inject SnackActionExecutor executor) {

        // 将 GRPC 的 Message 对象解析为 json
        factory.addEncoder(Message.class, new NodeEncoder<Message>() {
            @Override
            public void encode(Message message, ONode node) {
                String json = null;
                try {
                    json = JsonFormat.printer().includingDefaultValueFields().print(message);
                    ONode newNode = ONode.loadStr(json);
                    // 支持直接设置新的 节点
                    node.val(newNode);
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }
        });


        // 将 json参数直接解析为 GRPC 的 Message 对象
        executor.config().addDecoder(Message.class, new NodeDecoder<Message>() {
            @Override
            public Message decode(ONode node, Type type) {
                try {
                    node.rename("name-name", "owner");
                    String json = node.toJson();
                    Message.Builder builder = (Message.Builder) ((Class<?>) type).getMethod("newBuilder").invoke(null);
                    JsonFormat.parser().ignoringUnknownFields()
                            .merge(json, builder);
                    return builder.build();
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                    return null;
                }
            }
        });

        //log.info(factory.config().decoders().stream().map(Object::toString).collect(Collectors.joining("\n")));
        //log.info(factory.config().encoders().stream().map(Object::toString).collect(Collectors.joining("\n")));
    }

}
